﻿/*********************************************************************************
**                                                                              **
**  Copyright (C) 2024 LiLong                                                   **
**  This file is part of GnssLogs.                                              **
**                                                                              **
**  GnssLogs is free software: you can redistribute it and/or modify            **
**  it under the terms of the GNU Lesser General Public License as published by **
**  the Free Software Foundation, either version 3 of the License, or           **
**  (at your option) any later version.                                         **
**                                                                              **
**  GnssLogs is distributed in the hope that it will be useful,                 **
**  but WITHOUT ANY WARRANTY; without even the implied warranty of              **
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               **
**  GNU Lesser General Public License for more details.                         **
**                                                                              **
**  You should have received a copy of the GNU Lesser General Public License    **
**  along with GnssLogs.  If not, see <https://www.gnu.org/licenses/>.          **
**********************************************************************************/
#pragma once

#include "../ALIGNDOP.h"
#include "LogHeaderDecoder.h"

namespace GnssLogs
{
namespace ALIGNDOPDecoder
{
using namespace tao::pegtl;
using Sync   = TAO_PEGTL_STRING("#ALIGNDOPA");
using Header = LogHeaderDecoder::SyncExpression<Sync>;
// clang-format off
struct GDOP : Floating {};
struct PDOP : Floating {};
struct HDOP : Floating {};
struct HTDOP : Floating {};
struct TDOP : Floating {};
struct ElevMask : Floating {};
struct SatsCount : star<digit> {};
struct Sat : star<digit> {};
struct SatRule : seq<Split, Sat> {};
// clang-format on
using Expression = seq<Header,
                       GDOP,
                       Split,
                       PDOP,
                       Split,
                       HDOP,
                       Split,
                       HTDOP,
                       Split,
                       TDOP,
                       Split,
                       ElevMask,
                       Split,
                       SatsCount,
                       star<SatRule>,
                       one<'*'>,
                       CRC32,
                       Tail>;

template<typename T>
struct Action
{
};

template<>
struct Action<Header> : LogHeaderDecoder::LogHeaderHelperNoSetValue
{
};

template<>
struct Action<GDOP> : FloatHelper<Action<GDOP>>
{
    static void setValue(ALIGNDOP::Data& data, float value) { data.gdop = value; }
};

template<>
struct Action<PDOP> : FloatHelper<Action<PDOP>>
{
    static void setValue(ALIGNDOP::Data& data, float value) { data.pdop = value; }
};

template<>
struct Action<HDOP> : FloatHelper<Action<HDOP>>
{
    static void setValue(ALIGNDOP::Data& data, float value) { data.hdop = value; }
};

template<>
struct Action<HTDOP> : FloatHelper<Action<HTDOP>>
{
    static void setValue(ALIGNDOP::Data& data, float value) { data.htdop = value; }
};

template<>
struct Action<TDOP> : FloatHelper<Action<TDOP>>
{
    static void setValue(ALIGNDOP::Data& data, float value) { data.tdop = value; }
};

template<>
struct Action<ElevMask> : FloatHelper<Action<ElevMask>>
{
    static void setValue(ALIGNDOP::Data& data, float value) { data.elevMask = value; }
};

template<>
struct Action<SatsCount> : IntHelper<Action<SatsCount>, uint32_t>
{
    static void setValue(ALIGNDOP::Data& data, uint32_t value) { data.satsCount = value; }
};

template<>
struct Action<Sat> : IntHelper<Action<Sat>, uint32_t>
{
    static void setValue(ALIGNDOP::Data& data, uint32_t value) { data.sats.push_back(value); }
};

template<>
struct Action<CRC32> : CRC32Helper<Action<CRC32>>
{
    static void setValue(ALIGNDOP::Data& data, uint32_t value) { data.crc32 = value; }
};
} // namespace ALIGNDOPDecoder
} // namespace GnssLogs